Skip to content

Support GitHub Copilot CLI and improve CLI accounting#141

Merged
mike1858 merged 7 commits intoPiebald-AI:mainfrom
zhangzqs:copilot/support-copilot-cli-statistics
Apr 20, 2026
Merged

Support GitHub Copilot CLI and improve CLI accounting#141
mike1858 merged 7 commits intoPiebald-AI:mainfrom
zhangzqs:copilot/support-copilot-cli-statistics

Conversation

@zhangzqs
Copy link
Copy Markdown
Contributor

@zhangzqs zhangzqs commented Apr 9, 2026

Summary

  • split GitHub Copilot (VS Code) and GitHub Copilot CLI into separate analyzers/applications so they are tracked as distinct tools
  • improve Copilot CLI accounting by using shutdown model metrics for completed sessions and better cumulative-context estimation for active sessions
  • fill in Copilot CLI reasoning token tracking, plus add several built-in model prices and aliases observed in local data

What changed

  • added a dedicated GitHub Copilot CLI analyzer and Application::CopilotCli
  • kept the VS Code Copilot analyzer focused on chat session files only
  • made Copilot CLI parsing turn-aware and applied exact session.shutdown.data.modelMetrics usage to completed sessions
  • improved live-session estimates using accumulated context and compaction prompt overhead
  • populated Copilot CLI Reason Tks from reasoningText without changing the existing output/cost semantics
  • updated aggregation/session rollups so assistant messages are counted by role even when the model field is temporarily missing
  • added pricing entries/aliases for locally observed models, including reordered Claude names and extra built-in model mappings

Validation

  • cargo fmt --all --quiet
  • cargo build --quiet
  • cargo test --quiet
  • cargo clippy --quiet -- -D warnings
  • cargo doc --quiet

Notes

  • this PR was put together with a lot of vibe coding on real local Copilot CLI data, but the regression tests and verification steps are real and usable
  • pricing/alias coverage was also expanded for additional built-in models seen locally

Summary by CodeRabbit

  • New Features

    • Added support for GitHub Copilot CLI session logs as a data source
    • Added support for additional AI models: gpt-5.4-pro, kimi-k2.5, doubao-seed-2.0-code, minimax-m2.1, longcat-flash-lite, and an "auto" selector
  • Bug Fixes

    • Ensure assistant messages are counted and aggregated even when no model is recorded, improving stats accuracy
  • Documentation

    • Updated docs and UI to distinguish GitHub Copilot CLI from GitHub Copilot (VS Code)

Copilot AI and others added 5 commits April 8, 2026 03:04
Agent-Logs-Url: https://github.com/zhangzqs/splitrail/sessions/4ee476d9-1122-4625-b054-0d5921bb214e

Co-authored-by: zhangzqs <34616640+zhangzqs@users.noreply.github.com>
… precise token tracking

Separate Copilot CLI parsing from the VS Code analyzer into its own
module, add exact output token counts, context compaction handling,
and model-based cost calculation.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

Implements a new GitHub Copilot CLI analyzer parsing JSONL session logs, integrates it into the analyzer registry and UI strings, expands model catalog/aliases, and refactors message aggregation to count AI messages by assistant role rather than model presence.

Changes

Cohort / File(s) Summary
Copilot CLI Analyzer
src/analyzers/copilot_cli.rs
New analyzer (parsing ~/.copilot session/history events.jsonl): discovery, JSONL parsing, event reconstruction into conversation turns, token estimation, tool-call stats, session/project hashing, per-message hashes, and cost attribution using shutdown metrics or static overhead.
Analyzer Integration
src/analyzers/mod.rs, src/main.rs, src/mcp/server.rs
Added copilot_cli module, re-exported CopilotCliAnalyzer, registered analyzer in registry, and updated analyzer list description to include “GitHub Copilot CLI”.
Copilot (VS Code) analyzer tweaks
src/analyzers/copilot.rs, src/analyzers/tests/copilot.rs
Increased helper visibility to pub(crate), replaced local vscode fork array with module constant, explicit vector typing; added tests ensuring glob patterns exclude Copilot CLI session files.
Message aggregation & contribution logic
src/contribution_cache/single_session.rs, src/tui/logic.rs, src/utils.rs, src/utils/tests.rs
Refactored aggregation to gate AI-message counting and per-model increments on MessageRole::Assistant; adjusted TUI/stat accumulation and added unit test for assistant-without-model counting.
Models catalog
src/models.rs
Added canonical models (gpt-5.4-pro, kimi-k2.5, doubao-seed-2.0-code, minimax-m2.1, longcat-flash-lite, auto) with pricing/caching metadata and expanded MODEL_ALIASES; added unit tests for alias/pricing behavior.
Application type & UI/docs updates
src/types.rs, README.md, vscode-splitrail/README.md, src/tui.rs
Added CopilotCli enum variant; updated README and UI strings to include “GitHub Copilot CLI”.
Tests
src/analyzers/tests/copilot_cli.rs, src/analyzers/tests/mod.rs
New comprehensive tests for Copilot CLI analyzer (discovery, path recognition, JSONL parsing, event reconstruction, token/cost attribution, model inference); added test module reference.

Sequence Diagram(s)

sequenceDiagram
    participant FS as File System (~/ .copilot)
    participant Discovery as Data Discovery
    participant Parser as JSONL Parser
    participant Reconstructor as Event Reconstructor
    participant Calculator as Token & Cost Calculator
    participant Output as ConversationEmitter

    FS->>Discovery: Locate session-state / history-session-state
    Discovery->>Parser: Open matched events.jsonl
    Parser->>Reconstructor: Stream parsed JSON events
    Reconstructor->>Reconstructor: Correlate user.message ↔ assistant/tool events
    Reconstructor->>Calculator: Collect sessionId, cwd/gitRoot, message boundaries
    Calculator->>Calculator: Estimate tokens (input/output/cache), accumulate tool stats
    Calculator->>Calculator: Apply shutdown metrics or static overhead for cost
    Calculator->>Output: Emit ConversationMessage items with hashes and stats
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • mike1858
  • bl-ue

Poem

🐰 I hopped through logs at break of dawn,
Events in rows, until conversation’s drawn.
Tokens counted, models named with glee,
Copilot CLI now sings with me —
Costs and turns baked into memory. 🎩

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding support for GitHub Copilot CLI as a distinct analyzer and improving CLI token/cost accounting logic.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@zhangzqs
Copy link
Copy Markdown
Contributor Author

zhangzqs commented Apr 9, 2026

image

coderabbitai[bot]
coderabbitai Bot previously requested changes Apr 9, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/analyzers/copilot_cli.rs (2)

541-624: Consider grouping parameters into a context struct.

The flush_copilot_cli_turn function has 9 parameters. While the #[allow(clippy::too_many_arguments)] annotation acknowledges this, grouping related parameters (like conversation_hash, project_hash, session_name) into a context struct would improve readability and make future modifications easier.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/analyzers/copilot_cli.rs` around lines 541 - 624, The function
flush_copilot_cli_turn currently takes many related params—group
conversation_hash, project_hash, session_name (and optionally
user_index/assistant_index and live_context) into a small context struct to
reduce argument count and improve readability; create a CopilotCliFlushContext
(or similar) containing conversation_hash: String (or &str reference type
matching callers), project_hash: String, session_name: Option<String>, and if
helpful mutable indices user_index: usize and assistant_index: usize (or keep
indices separate if you prefer), update flush_copilot_cli_turn signature to
accept &mut CopilotCliFlushContext (and keep entries, current_turn,
live_context, pending_user as before), then update all call sites to build/pass
that context struct and adjust usage inside flush_copilot_cli_turn to reference
context.conversation_hash, context.project_hash, context.session_name, and
context.assistant_index (or &mut assistant_index) accordingly.

751-755: Using Utc::now() for missing timestamps may affect reproducibility.

When an event lacks a timestamp, the current time is used as a fallback. This means parsing the same file at different times could produce different date values for those messages. Consider logging a warning or using a sentinel value if reproducibility is a concern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/analyzers/copilot_cli.rs` around lines 751 - 755, The code sets
pending_user.date via event_timestamp.unwrap_or_else(Utc::now), which makes
parsing non-deterministic; change CopilotCliPendingUser.date to use a
reproducible sentinel or optional timestamp instead of calling Utc::now(), and
emit a warning when the event timestamp is missing; specifically, update the
creation of pending_user (the pending_user assignment and CopilotCliPendingUser
struct) to accept either Option<DateTime<Utc>> or a fixed sentinel (e.g., epoch)
and add a log call when event_timestamp.is_none() so missing timestamps are
recorded for debugging and reproducibility.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/tui.rs`:
- Line 1177: Update the no-data screen label that currently reads "GitHub
Copilot" to "GitHub Copilot (VS Code)" so it matches the analyzer split and
README wording; locate the string literal in src/tui.rs (the quoted message
shown) and replace that occurrence, and also search for other user-facing
occurrences of the plain "GitHub Copilot" label in the UI/strings to make the
naming consistent with "GitHub Copilot (VS Code)".

---

Nitpick comments:
In `@src/analyzers/copilot_cli.rs`:
- Around line 541-624: The function flush_copilot_cli_turn currently takes many
related params—group conversation_hash, project_hash, session_name (and
optionally user_index/assistant_index and live_context) into a small context
struct to reduce argument count and improve readability; create a
CopilotCliFlushContext (or similar) containing conversation_hash: String (or
&str reference type matching callers), project_hash: String, session_name:
Option<String>, and if helpful mutable indices user_index: usize and
assistant_index: usize (or keep indices separate if you prefer), update
flush_copilot_cli_turn signature to accept &mut CopilotCliFlushContext (and keep
entries, current_turn, live_context, pending_user as before), then update all
call sites to build/pass that context struct and adjust usage inside
flush_copilot_cli_turn to reference context.conversation_hash,
context.project_hash, context.session_name, and context.assistant_index (or &mut
assistant_index) accordingly.
- Around line 751-755: The code sets pending_user.date via
event_timestamp.unwrap_or_else(Utc::now), which makes parsing non-deterministic;
change CopilotCliPendingUser.date to use a reproducible sentinel or optional
timestamp instead of calling Utc::now(), and emit a warning when the event
timestamp is missing; specifically, update the creation of pending_user (the
pending_user assignment and CopilotCliPendingUser struct) to accept either
Option<DateTime<Utc>> or a fixed sentinel (e.g., epoch) and add a log call when
event_timestamp.is_none() so missing timestamps are recorded for debugging and
reproducibility.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fc410277-c73f-425d-ab4b-eed5041508f1

📥 Commits

Reviewing files that changed from the base of the PR and between f5ef1f4 and c3ab1b3.

📒 Files selected for processing (17)
  • README.md
  • src/analyzers/copilot.rs
  • src/analyzers/copilot_cli.rs
  • src/analyzers/mod.rs
  • src/analyzers/tests/copilot.rs
  • src/analyzers/tests/copilot_cli.rs
  • src/analyzers/tests/mod.rs
  • src/contribution_cache/single_session.rs
  • src/main.rs
  • src/mcp/server.rs
  • src/models.rs
  • src/tui.rs
  • src/tui/logic.rs
  • src/types.rs
  • src/utils.rs
  • src/utils/tests.rs
  • vscode-splitrail/README.md

Comment thread src/tui.rs
@zhangzqs zhangzqs changed the title Split GitHub Copilot CLI from VS Code Copilot and improve CLI accounting Support GitHub Copilot CLI and improve CLI accounting Apr 9, 2026
@mike1858 mike1858 enabled auto-merge (squash) April 19, 2026 21:43
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/models.rs (1)

972-988: ⚠️ Potential issue | 🔴 Critical

Correct M2.5 output pricing from $1.10 to $1.2 per 1M tokens.

M2.1 pricing of $0.30 / $1.20 is verified against official MiniMax API documentation and correctly marked is_estimated: false. However, M2.5 output pricing in the code is incorrect—official documentation shows M2.5 has identical pricing to M2.1 at $0.3 / $1.2 per 1M tokens, not $1.10 as currently set.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/models.rs` around lines 972 - 988, Update the MiniMax M2.5 entry so its
pricing matches M2.1: in the mapping key "minimax-m2.5" (ModelInfo) change the
PricingStructure::Flat output_per_1m from 1.10 to 1.20 so the pair becomes
input_per_1m: 0.30 and output_per_1m: 1.20, leaving caching
(CachingSupport::None) and is_estimated: false unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/models.rs`:
- Around line 1000-1008: The current addition of a literal "auto" ModelInfo
entry (PricingStructure::Flat(...), CachingSupport::None, is_estimated: true)
suppresses the existing warn_once("Unknown model: ...") path and can silently
make a real billed model named "auto" effectively free; remove or rework this
entry so real provider-reported "auto" still hits the unknown-model warning.
Either revert the "auto" map entry and handle routing selectors earlier in the
resolution code, or introduce a distinct flag/variant on ModelInfo (e.g.,
is_routing_selector or KnownButZero) and update the unknown-model warn logic to
only suppress warnings for entries marked as routing selectors while still
emitting a single debug/info log for known-zero models; reference the "auto"
mapping, ModelInfo, PricingStructure::Flat, CachingSupport::None, and
is_estimated when making the change.

---

Outside diff comments:
In `@src/models.rs`:
- Around line 972-988: Update the MiniMax M2.5 entry so its pricing matches
M2.1: in the mapping key "minimax-m2.5" (ModelInfo) change the
PricingStructure::Flat output_per_1m from 1.10 to 1.20 so the pair becomes
input_per_1m: 0.30 and output_per_1m: 1.20, leaving caching
(CachingSupport::None) and is_estimated: false unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e687fa6a-882c-496a-83f4-54586e7321e5

📥 Commits

Reviewing files that changed from the base of the PR and between c3ab1b3 and d081310.

📒 Files selected for processing (1)
  • src/models.rs

Comment thread src/models.rs
@mike1858 mike1858 merged commit 81e3efc into Piebald-AI:main Apr 20, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants